package se.jocke.nb.proxy.monitor.service.impl;

import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Queue;
import org.littleshoot.proxy.ChainedProxy;
import org.littleshoot.proxy.ChainedProxyAdapter;
import org.littleshoot.proxy.ChainedProxyManager;
import org.openide.util.Exceptions;

/**
 *
 * @author jocke
 */
public class ChainedProxyManagerImpl implements ChainedProxyManager {

    private final String targetHost;

    private final int targetPort;

    public ChainedProxyManagerImpl(String targetHost, int targetPort) {
        this.targetHost = targetHost;
        this.targetPort = targetPort;
    }

    @Override
    public void lookupChainedProxies(final HttpRequest hr, Queue<ChainedProxy> chainedProxies) {

        if (hr instanceof DefaultFullHttpRequest) {
            DefaultFullHttpRequest httpRequest = (DefaultFullHttpRequest) hr;
            HttpHeaders headers = httpRequest.headers();
            final String host = headers.get("Host");

            if (host != null) {
                chainedProxies.add(new ChainedProxyAdapter() {
                    @Override
                    public InetSocketAddress getChainedProxyAddress() {
                        try {
                            URL u = new URL(hr.getUri());

                            int port = u.getPort();

                            if (port == -1) {

                                if (hr.getUri().startsWith("https")) {
                                    port = 443;
                                
                                } else {
                                    port = 80;
                                }
                            }

                            return new InetSocketAddress(InetAddress.getByName(host), port);
                        } catch (UnknownHostException uhe) {
                            throw new RuntimeException("Unable to resolve " + host);
                        } catch (MalformedURLException ex) {
                            throw new RuntimeException("Unable to resolve " + host);
                        }
                    }
                });
                return;

            }
        }

        chainedProxies.add(new ChainedProxyAdapter() {
            @Override
            public InetSocketAddress getChainedProxyAddress() {
                try {
                    return new InetSocketAddress(InetAddress.getByName(targetHost), targetPort);
                } catch (UnknownHostException uhe) {
                    throw new RuntimeException("Unable to resolve " + targetHost);
                }
            }
        });
    }
}
